home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Extra 1996 #3 / AmigaPlus_CD-ROM-EXTRA_Nr.3.bin / aminet-spiele / zwei spieler / lordofhosts / lohsrc.lzh / moves.c < prev    next >
C/C++ Source or Header  |  1991-05-10  |  11KB  |  316 lines

  1. /* LORD OF HOSTS - moves.c --- Verarbeitung der Spielzüge */
  2.  
  3. #include "Lord.h"
  4.  
  5. extern UBYTE whatsonboard[8][8];
  6. extern UBYTE fval[16][8][8];
  7. extern UBYTE kval[16][8][8];
  8. extern struct Piece ThePieces[16];
  9. extern int status;
  10.  
  11. struct Move Moves[MAXUNDO];
  12. int undopos,redotop,undobot,last_error;
  13.  
  14. int NumPieces[2]= { 8,8 };
  15.  
  16. int check_move(UBYTE board[][8], struct Piece *Pieces, int Num,
  17.                UBYTE tox, UBYTE toy)
  18. {
  19.    int i,result=0, value = Pieces[Num].Value;
  20.    UBYTE fromx = Pieces[Num].x ,fromy = Pieces[Num].y,
  21.          base= (Num<8 ? 0 : 8);
  22.    /* Stimmt die Entfernung ? */
  23.    if (ABS(fromx-tox) + ABS(fromy-toy) < value) result = MUST_MOVE_FARTHER;
  24.    if (ABS(fromx-tox) + ABS(fromy-toy) > value) result = DIST_EXCEEDED;
  25.    /* Sitzt am Ende ein eigener Spielstein ? */
  26.    if (whatsonboard[tox][toy] >= base && whatsonboard[tox][toy] <= base+7)
  27.       result |= CANT_BEAT_BUDDY;
  28.    /* Ist der Weg frei ? */
  29.    result |= how_to_move(board,fromx,fromy,tox,toy);
  30.    /* Gerät durch diesen Zug der eigene King in Gefahr ? */
  31.    if (result == MOVE_X_FIRST || result == MOVE_Y_FIRST)
  32.       result |= check_check(board,Pieces,Num,tox,toy);
  33.    return result;
  34. }
  35.  
  36. int how_to_move(UBYTE board[][8],
  37.                 UBYTE fromx, UBYTE fromy, UBYTE tox, UBYTE toy)
  38. {
  39.    int xdist = tox-fromx, ydist = toy-fromy,
  40.        xstep = 0, ystep = 0, i;
  41.    BOOL freexfirst = TRUE, freeyfirst = TRUE;
  42.    if (xdist) xstep = xdist / ABS(xdist);
  43.    if (ydist) ystep = ydist / ABS(ydist);
  44.    /* Ohne Abbiegen ? */
  45.    if (!ydist)
  46.    {
  47.       for (i=fromx+xstep; i!=tox; i+=xstep)
  48.          if (board[i][fromy] != NOT_OCCUPIED) freexfirst = FALSE;
  49.       if (freexfirst) return MOVE_X_FIRST; else return WAY_BLOCKED;
  50.    }
  51.    if (!xdist)
  52.    {
  53.       for (i=fromy+ystep; i!=toy; i+=ystep)
  54.          if (board[fromx][i] != NOT_OCCUPIED) freeyfirst = FALSE;
  55.       if (freeyfirst) return MOVE_Y_FIRST; else return WAY_BLOCKED;
  56.    }
  57.    /* Mit Abbiegen */
  58.    /* Geht's, wenn wir zuerst in x-Richtung laufen ? */
  59.    for (i=fromx+xstep; i!=tox+xstep; i+=xstep)
  60.       if (board[i][fromy] != NOT_OCCUPIED) freexfirst = FALSE;
  61.    if (freexfirst)
  62.       for (i=fromy+ystep; i!=toy; i+=ystep)
  63.          if (board[tox][i] != NOT_OCCUPIED) freexfirst = FALSE;
  64.    if (!freexfirst) /* Wenn nicht, geht's dann mit y zuerst ? */
  65.    {
  66.       for (i=fromy+ystep; i!=toy+ystep; i+=ystep)
  67.          if (board[fromx][i] != NOT_OCCUPIED) freeyfirst = FALSE;
  68.       if (freeyfirst)
  69.          for (i=fromx+xstep; i!=tox; i+=xstep)
  70.             if (board[i][toy] != NOT_OCCUPIED) freeyfirst = FALSE;
  71.    }
  72.  
  73.    if (freexfirst) return MOVE_X_FIRST;
  74.    if (freeyfirst) return MOVE_Y_FIRST;
  75.    return WAY_BLOCKED;
  76. }
  77.  
  78. int check_check(UBYTE board[][8], struct Piece *Pieces, int Num,
  79.                UBYTE tox, UBYTE toy)
  80. {
  81.    UBYTE checkboard[8][8], checkx, checky, fromx, fromy;
  82.    int i,j,result,base = (Num<8 ? 0 : 8), value;
  83.    for (i=0; i<=7; ++i)
  84.       for (j=0; j<=7; ++j)
  85.          checkboard[i][j] = board[i][j];
  86.    checkboard[tox][toy] = Num;
  87.    checkboard[Pieces[Num].x][Pieces[Num].y] = NOT_OCCUPIED;
  88.    if (Num != base)
  89.    {
  90.       checkx = Pieces[base].x;
  91.       checky = Pieces[base].y;
  92.    }
  93.    else
  94.    {
  95.       checkx = tox;
  96.       checky = toy;
  97.    }
  98.    j = 8 - base;
  99.    for (i=j; i<=j+7; ++i)
  100.    {
  101.       fromx = Pieces[i].x;
  102.       fromy = Pieces[i].y;
  103.       value = Pieces[i].Value;
  104.       if (Pieces[i].StillAlive == TRUE)
  105.          if (!(fromx == tox && fromy == toy))
  106.          {
  107.             if (ABS(fromx-checkx) + ABS(fromy-checky) == value)
  108.             {
  109.                result = how_to_move(checkboard,fromx,fromy,checkx,checky);
  110.                if (result == MOVE_X_FIRST || result == MOVE_Y_FIRST)
  111.                   return KING_IN_DANGER;
  112.             }
  113.          }
  114.    }
  115.    return 0;
  116. }
  117.  
  118. int do_move(UBYTE board[][8], struct Piece *Pieces, int Num,
  119.             UBYTE tox, UBYTE toy, BOOL x_first)
  120. {
  121.    UBYTE fromx = Pieces[Num].x, fromy = Pieces[Num].y,checkvalue;
  122.    int result=0,color,base,p,i,j,r2,beaten;
  123.    SetPiece(Pieces[Num], FALSE, TRUE);/* nicht einblenden, Ausblendfarbe an */
  124.    if (x_first)
  125.    {
  126.       MovePiece(fromx,fromy,tox-fromx,0,TRUE);
  127.       if (toy != fromy) MovePiece(tox,fromy,0,toy-fromy,FALSE);
  128.    }
  129.    else
  130.    {
  131.       MovePiece(fromx,fromy,0,toy-fromy,TRUE);
  132.       if (tox != fromx) MovePiece(fromx,toy,tox-fromx,0,FALSE);
  133.    }
  134.    board[fromx][fromy] = NOT_OCCUPIED;
  135.    beaten = NOBODY;
  136.    if (board[tox][toy] != NOT_OCCUPIED)
  137.    {
  138.       beaten = board[tox][toy];
  139.       result |= ENEMY_KNIGHT_BEATEN;
  140.       Pieces[board[tox][toy]].StillAlive = FALSE;
  141.       color = (Num < 8 ? 1 : 0); /* color = Farbe des Gegners */
  142.       --NumPieces[color];
  143.       if (NumPieces[color] < 3)
  144.          result |= ENEMY_OUT_OF_KNIGHTS;    /* Spiel gewonnen */
  145.    }
  146.    board[tox][toy] = Num;
  147.    Pieces[Num].x = tox;
  148.    Pieces[Num].y = toy;
  149.    Pieces[Num].Value = fval[Num][tox][toy];
  150.    SetPiece(Pieces[Num], TRUE, FALSE);   /* einblenden, keine Ausblendfarbe */
  151.    /* Moves[] für Undo/Redo setzen */
  152.    Moves[undopos].fromx = fromx;
  153.    Moves[undopos].fromy = fromy;
  154.    Moves[undopos].tox   = tox;
  155.    Moves[undopos].toy   = toy;
  156.    Moves[undopos].Beaten= beaten;
  157.    Moves[undopos].x_first = x_first;
  158.    Moves[undopos].status = status | WAITING_FOR_PICK;
  159.    Moves[undopos].status &= (~(WAITING_FOR_DEST|WAITING_FOR_CONF));
  160.    /* undopos : Position im Undo/Redo-Puffer
  161.     * redotop : wenn undopos == redotop, dann ist kein Redo möglich
  162.     * undobot : wenn undopos == undobot, dann ist kein Undo möglich */
  163.    undopos = (undopos+1) % MAXUNDO;
  164.    if (undopos == undobot) undobot = (undobot+1) % MAXUNDO;
  165.    redotop = undopos;
  166.    /* Check, ob Check */
  167.    base = (Num < 8 ? 0 : 8);
  168.    tox = Pieces[8-base].x;
  169.    toy = Pieces[8-base].y;
  170.    for (i=base; i<=base+7; ++i)
  171.    {
  172.       fromx=Pieces[i].x;
  173.       fromy=Pieces[i].y;
  174.       if (Pieces[i].StillAlive == TRUE)
  175.       {
  176.          checkvalue = Pieces[i].Value;
  177.          if (checkvalue == 0) checkvalue =kval[i][Pieces[i].x][Pieces[i].y];
  178.          if (ABS(fromx-tox) + ABS(fromy-toy) == checkvalue)
  179.          {                    /* Pieces[i].Value geht nicht, da er mit
  180.                                  kval[i][x][y] ausgetauscht sein könnte ! */
  181.             r2 = how_to_move(board,fromx,fromy,tox,toy);
  182.             if (r2 == MOVE_X_FIRST || r2 == MOVE_Y_FIRST)
  183.                result |= ENEMY_KING_BEATABLE;
  184.          }
  185.       }
  186.    }
  187.    /* Check, ob Matt */
  188.    if (result & ENEMY_KING_BEATABLE)
  189.    {
  190.       r2=1;
  191.       for (p = 8-base; p<=15-base && r2 > 0; ++p)  /* gegnerische Spielsteine */
  192.       {
  193.          if (Pieces[p].StillAlive)
  194.          {
  195.             for (i=-Pieces[p].Value; i<=Pieces[p].Value && r2 > 0; ++i)
  196.             {
  197.                j=Pieces[p].Value-ABS(i); /* ABS(i)+ABS(j) = Value */
  198.                if (Pieces[p].x+i >=0 && Pieces[p].x+i <=7
  199.                 && Pieces[p].y+j >=0 && Pieces[p].y+j <=7)
  200.                {
  201.                   r2 = check_move(board,Pieces,p,Pieces[p].x+i,Pieces[p].y+j);
  202.                   if (r2 == MOVE_X_FIRST || r2 == MOVE_Y_FIRST)
  203.                      r2=-1;
  204.                }
  205.                if (r2 > 0)
  206.                {
  207.                   j=-Pieces[p].Value+ABS(i); /* ABS(i)+ABS(j) = Value */
  208.                   if (Pieces[p].x+i >=0 && Pieces[p].x+i <=7
  209.                    && Pieces[p].y+j >=0 && Pieces[p].y+j <=7)
  210.                   {
  211.                      r2 = check_move(board,Pieces,p,Pieces[p].x+i,Pieces[p].y+j);
  212.                      if (r2 == MOVE_X_FIRST || r2 == MOVE_Y_FIRST)
  213.                         r2=-1;
  214.                   }
  215.                }
  216.             }
  217.          }
  218.       }
  219.       if (r2 != -1)
  220.          result |= ENEMY_MATED;
  221.    }
  222.    if (result & ENEMY_OUT_OF_KNIGHTS || result & ENEMY_MATED)
  223.       Moves[undopos].GameOver = TRUE;
  224.    else
  225.       Moves[undopos].GameOver = FALSE;
  226.    return result;
  227. }
  228.  
  229. BOOL undo(void)
  230. {
  231.    int Num;
  232.    UBYTE fromx,fromy,tox,toy;
  233.    if (undobot == undopos) return FALSE;  /* konnte Undo nicht durchführen */
  234.    --undopos;
  235.    if (undopos < 0) undopos += MAXUNDO;    /* wraparound buffer */
  236.  
  237.    fromx = Moves[undopos].tox;   /* Undo vertauscht hin und zurück */
  238.    fromy = Moves[undopos].toy;
  239.    tox   = Moves[undopos].fromx;
  240.    toy   = Moves[undopos].fromy;
  241.    Num = whatsonboard[fromx][fromy];
  242.    SetPiece(ThePieces[Num], FALSE, TRUE);/* nicht einblenden, Ausblendfarbe an */
  243.    if (!Moves[undopos].x_first)
  244.    {
  245.       if (tox != fromx)
  246.       {
  247.          MovePiece(fromx,fromy,tox-fromx,0,TRUE);
  248.          MovePiece(tox,fromy,0,toy-fromy,FALSE);
  249.       }
  250.       else
  251.          MovePiece(fromx,fromy,0,toy-fromy,TRUE);
  252.    }
  253.    else   /* x_first == TRUE */
  254.    {
  255.       if (toy != fromy)
  256.       {
  257.          MovePiece(fromx,fromy,0,toy-fromy,TRUE);
  258.          MovePiece(fromx,toy,tox-fromx,0,FALSE);
  259.       }
  260.       else
  261.          MovePiece(fromx,fromy,tox-fromx,0,TRUE);
  262.    }
  263.    ThePieces[Num].x = tox;
  264.    ThePieces[Num].y = toy;
  265.    ThePieces[Num].Value = fval[Num][tox][toy];
  266.    whatsonboard[tox][toy] = Num;
  267.    whatsonboard[fromx][fromy] = NOT_OCCUPIED;
  268.    SetPiece(ThePieces[Num], TRUE, FALSE); /* einblenden, keine Ausblendfarbe */
  269.    if (Moves[undopos].Beaten != NOBODY)
  270.    {
  271.       ThePieces[Moves[undopos].Beaten].StillAlive = TRUE;  /* Revival */
  272.       SetPiece(ThePieces[Moves[undopos].Beaten], TRUE, FALSE);
  273.       whatsonboard[fromx][fromy] = Moves[undopos].Beaten;
  274.       NumPieces[(Moves[undopos].Beaten > 7)]++;
  275.    }
  276.    return TRUE;
  277. }
  278.  
  279. BOOL redo(void)
  280. {
  281.    int Num;
  282.    UBYTE fromx,fromy,tox,toy;
  283.    if (redotop == undopos) return FALSE;  /* konnte Redo nicht durchführen */
  284.  
  285.    fromx = Moves[undopos].fromx;
  286.    fromy = Moves[undopos].fromy;
  287.    tox   = Moves[undopos].tox;
  288.    toy   = Moves[undopos].toy;
  289.    Num = whatsonboard[fromx][fromy];
  290.    SetPiece(ThePieces[Num], FALSE, TRUE);/* nicht einblenden, Ausblendfarbe an */
  291.    if (Moves[undopos].x_first)
  292.    {
  293.       MovePiece(fromx,fromy,tox-fromx,0,TRUE);
  294.       if (toy != fromy) MovePiece(tox,fromy,0,toy-fromy,FALSE);
  295.    }
  296.    else
  297.    {
  298.       MovePiece(fromx,fromy,0,toy-fromy,TRUE);
  299.       if (tox != fromx) MovePiece(fromx,toy,tox-fromx,0,FALSE);
  300.    }
  301.    ThePieces[Num].x = tox;
  302.    ThePieces[Num].y = toy;
  303.    ThePieces[Num].Value = fval[Num][tox][toy];
  304.    whatsonboard[tox][toy] = Num;
  305.    whatsonboard[fromx][fromy] = NOT_OCCUPIED;
  306.    SetPiece(ThePieces[Num], TRUE, FALSE); /* einblenden, keine Ausblendfarbe */
  307.    if (Moves[undopos].Beaten != NOBODY)
  308.    {
  309.       ThePieces[Moves[undopos].Beaten].StillAlive = FALSE;  /* Wieder tot */
  310.       NumPieces[(Moves[undopos].Beaten>7)]--;
  311.    }
  312.    undopos = (undopos+1) % MAXUNDO;       /* wraparound buffer */
  313.    return TRUE;
  314. }
  315.  
  316.